@neko-os/ui 0.0.2 → 0.0.4

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 (103) hide show
  1. package/dist/NekoUI.js +1 -0
  2. package/dist/abstractions/Icon.js +1 -0
  3. package/dist/abstractions/Icon.native.js +1 -0
  4. package/dist/abstractions/Icon.web.js +1 -0
  5. package/dist/abstractions/Text.js +1 -0
  6. package/dist/abstractions/Text.native.js +1 -0
  7. package/dist/abstractions/Text.web.js +1 -0
  8. package/dist/abstractions/TouchableOpacity.js +1 -0
  9. package/dist/abstractions/View.js +1 -1
  10. package/dist/abstractions/View.native.js +1 -0
  11. package/dist/abstractions/View.web.js +1 -0
  12. package/dist/actions/Button.js +1 -0
  13. package/dist/actions/index.js +1 -0
  14. package/dist/helpers/string.js +1 -0
  15. package/dist/index.css +68 -0
  16. package/dist/index.js +1 -1
  17. package/dist/modifiers/background.js +1 -0
  18. package/dist/modifiers/border.js +1 -0
  19. package/dist/modifiers/flexWrapper.js +1 -1
  20. package/dist/modifiers/fullColor.js.js +1 -0
  21. package/dist/modifiers/margin.js +1 -1
  22. package/dist/modifiers/padding.js +1 -1
  23. package/dist/modifiers/shadow.js +1 -0
  24. package/dist/modifiers/size.js +1 -1
  25. package/dist/modifiers/text.js +1 -1
  26. package/dist/presentation/Icon.js +1 -0
  27. package/dist/presentation/Tag.js +1 -0
  28. package/dist/presentation/index.js +1 -0
  29. package/dist/structure/Card.js +1 -0
  30. package/dist/structure/View.js +1 -1
  31. package/dist/structure/index.js +1 -1
  32. package/dist/text/Text.js +1 -0
  33. package/dist/text/index.js +1 -0
  34. package/dist/theme/ThemeHandler.js +1 -1
  35. package/dist/theme/default/base.js +1 -0
  36. package/dist/theme/default/base.native.js +1 -0
  37. package/dist/theme/default/base.web.js +1 -0
  38. package/dist/theme/default/cyberpunkTheme.js +1 -0
  39. package/dist/theme/default/darkTheme.js +1 -0
  40. package/dist/theme/default/deepWoodsTheme.js +1 -0
  41. package/dist/theme/default/forestTheme.js +1 -0
  42. package/dist/theme/default/lightTheme.js +1 -0
  43. package/dist/theme/default/midnightTheme.js +1 -0
  44. package/dist/theme/default/oceanTheme.js +1 -0
  45. package/dist/theme/default/pastelTheme.js +1 -0
  46. package/dist/theme/default/sunsetTheme.js +1 -0
  47. package/dist/theme/default/themes.js +1 -0
  48. package/dist/theme/format/colorsVariations.js +1 -0
  49. package/dist/theme/format/formatTheme.js +1 -0
  50. package/dist/theme/helpers/sizeScale.js +1 -0
  51. package/dist/theme/index.js +1 -1
  52. package/package.json +8 -3
  53. package/src/NekoUI.js +5 -0
  54. package/src/abstractions/Icon.js +26 -0
  55. package/src/abstractions/Icon.native.js +2 -0
  56. package/src/abstractions/Icon.web.js +2 -0
  57. package/src/abstractions/Text.js +3 -0
  58. package/src/abstractions/Text.native.js +3 -0
  59. package/src/abstractions/Text.web.js +3 -0
  60. package/src/abstractions/TouchableOpacity.js +12 -0
  61. package/src/abstractions/View.js +2 -13
  62. package/src/abstractions/View.native.js +3 -0
  63. package/src/abstractions/View.web.js +3 -0
  64. package/src/actions/Button.js +48 -0
  65. package/src/actions/index.js +1 -0
  66. package/src/helpers/string.js +57 -0
  67. package/src/index.css +68 -0
  68. package/src/index.js +6 -3
  69. package/src/modifiers/background.js +19 -0
  70. package/src/modifiers/border.js +53 -0
  71. package/src/modifiers/flexWrapper.js +4 -1
  72. package/src/modifiers/fullColor.js.js +30 -0
  73. package/src/modifiers/margin.js +6 -4
  74. package/src/modifiers/padding.js +6 -4
  75. package/src/modifiers/shadow.js +32 -0
  76. package/src/modifiers/size.js +36 -4
  77. package/src/modifiers/text.js +29 -4
  78. package/src/presentation/Icon.js +14 -0
  79. package/src/presentation/Tag.js +32 -0
  80. package/src/presentation/index.js +2 -0
  81. package/src/structure/Card.js +36 -0
  82. package/src/structure/View.js +15 -3
  83. package/src/structure/index.js +1 -0
  84. package/src/text/Text.js +20 -0
  85. package/src/text/index.js +1 -0
  86. package/src/theme/ThemeHandler.js +56 -2
  87. package/src/theme/default/base.js +65 -0
  88. package/src/theme/default/base.native.js +58 -0
  89. package/src/theme/default/base.web.js +3 -0
  90. package/src/theme/default/cyberpunkTheme.js +30 -0
  91. package/src/theme/default/darkTheme.js +30 -0
  92. package/src/theme/default/deepWoodsTheme.js +30 -0
  93. package/src/theme/default/forestTheme.js +30 -0
  94. package/src/theme/default/lightTheme.js +30 -0
  95. package/src/theme/default/midnightTheme.js +30 -0
  96. package/src/theme/default/oceanTheme.js +30 -0
  97. package/src/theme/default/pastelTheme.js +30 -0
  98. package/src/theme/default/sunsetTheme.js +31 -0
  99. package/src/theme/default/themes.js +21 -0
  100. package/src/theme/format/colorsVariations.js +31 -0
  101. package/src/theme/format/formatTheme.js +22 -0
  102. package/src/theme/helpers/sizeScale.js +7 -0
  103. package/src/theme/index.js +1 -0
package/src/index.css ADDED
@@ -0,0 +1,68 @@
1
+ :root {
2
+ font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
3
+ line-height: 1.5;
4
+ font-weight: 400;
5
+
6
+ color: #213547;
7
+ background-color: #ffffff;
8
+
9
+ font-synthesis: none;
10
+ text-rendering: optimizeLegibility;
11
+ -webkit-font-smoothing: antialiased;
12
+ -moz-osx-font-smoothing: grayscale;
13
+ }
14
+
15
+ *,
16
+ * * {
17
+ box-sizing: border-box;
18
+ }
19
+
20
+ #root,
21
+ body {
22
+ margin: 0;
23
+ display: flex;
24
+ width: 100%;
25
+ min-height: 100vh;
26
+ }
27
+
28
+ .neko-wave-click-effect {
29
+ position: relative;
30
+ padding: 10px 20px;
31
+ background: #1677ff;
32
+ color: white;
33
+ border: none;
34
+ border-radius: 4px;
35
+ cursor: pointer;
36
+ overflow: hidden;
37
+ }
38
+
39
+ .neko-wave-click-effect:after {
40
+ content: '';
41
+ position: absolute;
42
+ left: 0;
43
+ top: 0;
44
+ right: 0;
45
+ bottom: 0;
46
+ border: 2px solid rgba(200, 200, 200, 0.5);
47
+ opacity: 0;
48
+ transform: scale(0.9);
49
+ }
50
+
51
+ .neko-wave-click-effect:active:after {
52
+ animation: wave-effect 0.4s ease-out;
53
+ }
54
+
55
+ .neko-wave-click-effect:hover {
56
+ opacity: 0.95;
57
+ }
58
+
59
+ @keyframes wave-effect {
60
+ 0% {
61
+ opacity: 1;
62
+ transform: scale(0.9);
63
+ }
64
+ 100% {
65
+ opacity: 0;
66
+ transform: scale(1.3);
67
+ }
68
+ }
package/src/index.js CHANGED
@@ -1,6 +1,9 @@
1
1
  // export * from './form'
2
2
  export * from './structure'
3
- //
4
- // export const View = 10
3
+ export * from './actions'
4
+ export * from './presentation'
5
+ export * from './text'
6
+ export * from './theme'
7
+ export * from './NekoUI'
5
8
 
6
- export const version = 8
9
+ export const version = 41
@@ -0,0 +1,19 @@
1
+ import { clearProps } from './_helpers'
2
+ import { useGetColor } from '../theme/ThemeHandler'
3
+
4
+ export function useBackgroundModifier(props) {
5
+ const getColor = useGetColor()
6
+ let { bg, background, backgroundColor, ...restProps } = props
7
+
8
+ backgroundColor = getColor(bg ?? background ?? backgroundColor)
9
+
10
+ const style = clearProps({ backgroundColor })
11
+
12
+ return {
13
+ ...restProps,
14
+ style: {
15
+ ...props.style,
16
+ ...style,
17
+ },
18
+ }
19
+ }
@@ -0,0 +1,53 @@
1
+ import { clearProps } from './_helpers'
2
+ import { useGetColor, useGetRadius } from '../theme/ThemeHandler'
3
+
4
+ export function useBorderModifier(props) {
5
+ const getRadius = useGetRadius()
6
+ const getColor = useGetColor()
7
+ let {
8
+ br,
9
+ brT,
10
+ borderRadiusT,
11
+ brB,
12
+ borderRadiusB,
13
+ brL,
14
+ borderRadiusL,
15
+ brR,
16
+ borderRadiusR,
17
+ borderRadius,
18
+ borderStyle,
19
+ borderWidth,
20
+ borderColor,
21
+ brColor,
22
+ round,
23
+ ...restProps
24
+ } = props
25
+
26
+ if (round) br = 1000
27
+ const borderTopRightRadius = getRadius(brT ?? borderRadiusT ?? brR ?? borderRadiusR ?? borderRadius ?? br)
28
+ const borderTopLeftRadius = getRadius(brT ?? borderRadiusT ?? brL ?? borderRadiusL ?? borderRadius ?? br)
29
+ const borderBottomRightRadius = getRadius(brB ?? borderRadiusB ?? brR ?? borderRadiusR ?? borderRadius ?? br)
30
+ const borderBottomLeftRadius = getRadius(brB ?? borderRadiusB ?? brL ?? borderRadiusL ?? borderRadius ?? br)
31
+
32
+ if (!!borderColor || brColor) borderColor = getColor(brColor ?? borderColor)
33
+
34
+ borderStyle = borderStyle
35
+ if (!!borderWidth) borderStyle = 'solid'
36
+ const style = clearProps({
37
+ borderStyle,
38
+ borderTopRightRadius,
39
+ borderTopLeftRadius,
40
+ borderBottomRightRadius,
41
+ borderBottomLeftRadius,
42
+ borderColor,
43
+ borderWidth,
44
+ })
45
+
46
+ return {
47
+ ...restProps,
48
+ style: {
49
+ ...props.style,
50
+ ...style,
51
+ },
52
+ }
53
+ }
@@ -1,12 +1,15 @@
1
1
  import { clearProps } from './_helpers'
2
+ import { useGetSpace } from '../theme/ThemeHandler'
2
3
 
3
4
  export function useFlexWrapperModifier(props) {
4
- const { justify, align, center, centerV, centerH, toRight, toBottom, direction, row, wrap, gap, ...restProps } = props
5
+ const getSpace = useGetSpace()
6
+ let { justify, align, center, centerV, centerH, toRight, toBottom, direction, row, wrap, gap, ...restProps } = props
5
7
 
6
8
  let justifyContent = justify
7
9
  let alignItems = align
8
10
  let flexDirection = direction || 'column'
9
11
  let flexWrap
12
+ gap = getSpace(gap)
10
13
 
11
14
  if (center) {
12
15
  justifyContent = 'center'
@@ -0,0 +1,30 @@
1
+ import tinycolor from 'tinycolor2'
2
+
3
+ import { useGetColor } from '../theme/ThemeHandler'
4
+
5
+ export function useFullColorModifier(props) {
6
+ const getColor = useGetColor()
7
+ let { color, outline, ...restProps } = props
8
+
9
+ let bg = color
10
+ const bgObj = tinycolor(getColor(bg))
11
+ let borderColor = color
12
+ let textColor = 'text'
13
+ let textColorObj = tinycolor(getColor('text'))
14
+
15
+ if (!!outline) {
16
+ bg = 'transparent'
17
+ textColor = color
18
+ } else if (bgObj.isDark() === textColorObj.isDark()) {
19
+ textColor = 'overlayBG'
20
+ }
21
+
22
+ return [
23
+ textColor,
24
+ {
25
+ ...restProps,
26
+ bg,
27
+ borderColor,
28
+ },
29
+ ]
30
+ }
@@ -1,12 +1,14 @@
1
1
  import { clearProps } from './_helpers'
2
+ import { useGetSpace } from '../theme/ThemeHandler'
2
3
 
3
4
  export function useMarginModifier(props) {
5
+ const getSpace = useGetSpace()
4
6
  const { marginT, marginB, marginL, marginR, marginV, marginH, margin, ...restProps } = props
5
7
 
6
- const marginTop = marginT ?? marginV ?? margin
7
- const marginBottom = marginB ?? marginV ?? margin
8
- const marginRight = marginR ?? marginH ?? margin
9
- const marginLeft = marginL ?? marginH ?? margin
8
+ const marginTop = getSpace(marginT ?? marginV ?? margin)
9
+ const marginBottom = getSpace(marginB ?? marginV ?? margin)
10
+ const marginRight = getSpace(marginR ?? marginH ?? margin)
11
+ const marginLeft = getSpace(marginL ?? marginH ?? margin)
10
12
 
11
13
  const style = clearProps({ marginTop, marginBottom, marginRight, marginLeft })
12
14
 
@@ -1,12 +1,14 @@
1
1
  import { clearProps } from './_helpers'
2
+ import { useGetSpace } from '../theme/ThemeHandler'
2
3
 
3
4
  export function usePaddingModifier(props) {
5
+ const getSpace = useGetSpace()
4
6
  const { paddingT, paddingB, paddingL, paddingR, paddingV, paddingH, padding, ...restProps } = props
5
7
 
6
- const paddingTop = paddingT ?? paddingV ?? padding
7
- const paddingBottom = paddingB ?? paddingV ?? padding
8
- const paddingRight = paddingR ?? paddingH ?? padding
9
- const paddingLeft = paddingL ?? paddingH ?? padding
8
+ const paddingTop = getSpace(paddingT ?? paddingV ?? padding)
9
+ const paddingBottom = getSpace(paddingB ?? paddingV ?? padding)
10
+ const paddingRight = getSpace(paddingR ?? paddingH ?? padding)
11
+ const paddingLeft = getSpace(paddingL ?? paddingH ?? padding)
10
12
 
11
13
  const style = clearProps({ paddingTop, paddingBottom, paddingRight, paddingLeft })
12
14
 
@@ -0,0 +1,32 @@
1
+ import { clearProps } from './_helpers'
2
+ import { useGetColor } from '../theme/ThemeHandler'
3
+
4
+ export function useShadowModifier(props) {
5
+ const getColor = useGetColor()
6
+ let { shadow, ...restProps } = props
7
+
8
+ let boxShadow, shadowRadius, shadowOffset, shadowOpacity, shadowColor, elevation
9
+ if (shadow === true) {
10
+ shadow = getColor('shadow')
11
+ } else if (!!shadow) {
12
+ shadow = getColor(shadow)
13
+ }
14
+ if (!!shadow) {
15
+ boxShadow = `0 1px 10px ${shadow}`
16
+ shadowRadius = 10
17
+ shadowOffset = { width: 0, height: 1 }
18
+ shadowOpacity = 1
19
+ elevation = 10
20
+ shadowColor = shadow
21
+ }
22
+
23
+ const style = clearProps({ boxShadow, shadowRadius, shadowOffset, shadowOpacity, shadowColor, elevation })
24
+
25
+ return {
26
+ ...restProps,
27
+ style: {
28
+ ...props.style,
29
+ ...style,
30
+ },
31
+ }
32
+ }
@@ -1,11 +1,43 @@
1
1
  import { clearProps } from './_helpers'
2
+ import { useGetElementHeight } from '../theme/ThemeHandler'
2
3
 
3
4
  export function useSizeModifier(props) {
4
- let { width, height, fullWidth, fullHeight, ...restProps } = props || {}
5
- if (fullWidth) width = '100%'
6
- if (fullHeight) height = '100%'
5
+ const getHeight = useGetElementHeight()
6
+ let {
7
+ width,
8
+ height,
9
+ minH,
10
+ minHeight,
11
+ maxH,
12
+ maxHeight,
13
+ minWidth,
14
+ minW,
15
+ maxWidth,
16
+ maxW,
17
+ fullWidth,
18
+ fullW,
19
+ fullHeight,
20
+ fullH,
21
+ ratio,
22
+ square,
23
+ ...restProps
24
+ } = props || {}
7
25
 
8
- const style = clearProps({ height, width })
26
+ minHeight = getHeight(minHeight || minH)
27
+ minWidth = minWidth || minW
28
+
29
+ maxHeight = maxHeight || maxH
30
+ maxWidth = maxWidth || maxW
31
+
32
+ height = getHeight(height)
33
+
34
+ if (fullWidth || fullW) width = '100%'
35
+ if (fullHeight || fullH) height = '100%'
36
+
37
+ let aspectRatio = ratio
38
+ if (!!square) aspectRatio = 1
39
+
40
+ const style = clearProps({ height, width, minHeight, minHeight, maxHeight, maxWidth, aspectRatio })
9
41
 
10
42
  return {
11
43
  ...restProps,
@@ -1,7 +1,29 @@
1
1
  import { clearProps } from './_helpers'
2
+ import { mergePreset, useGetColor, useTexts } from '../theme/ThemeHandler'
2
3
 
3
- export function useTextModifier(props) {
4
- let { opacity, bold, strong, fontWeight, italic, underline, lineHeight, align, center, toRight, ...restProps } = props
4
+ export function useTextModifier({ size, ...props }) {
5
+ const getColor = useGetColor()
6
+ const texts = useTexts()
7
+
8
+ if (!size && !props.inherit) size = 'p'
9
+
10
+ let {
11
+ color,
12
+ opacity,
13
+ bold,
14
+ strong,
15
+ fontWeight,
16
+ weight,
17
+ italic,
18
+ underline,
19
+ lineHeight,
20
+ align,
21
+ center,
22
+ toRight,
23
+ inherit,
24
+ fontSize,
25
+ ...restProps
26
+ } = mergePreset(texts, size, props, 'p')
5
27
 
6
28
  let fontStyle
7
29
  if (italic) fontStyle = 'italic'
@@ -13,8 +35,11 @@ export function useTextModifier(props) {
13
35
  if (center) textAlign = 'center'
14
36
  if (toRight) textAlign = 'right'
15
37
 
38
+ fontWeight = fontWeight || weight
16
39
  if (bold || strong) fontWeight = 600
17
40
 
41
+ if (!inherit) color = getColor(color || 'text')
42
+
18
43
  const style = clearProps({
19
44
  fontWeight,
20
45
  fontStyle,
@@ -22,10 +47,10 @@ export function useTextModifier(props) {
22
47
  lineHeight,
23
48
  textAlign,
24
49
  opacity,
50
+ color,
51
+ fontSize,
25
52
  })
26
53
 
27
- // TODO: Handle font sizes based on theme
28
-
29
54
  return {
30
55
  ...restProps,
31
56
  style: {
@@ -0,0 +1,14 @@
1
+ import { AbsIcon } from '../abstractions/Icon'
2
+ import { useGetColor, useMergeThemeComponent } from '../theme/ThemeHandler'
3
+
4
+ export function Icon({ name, color, ...rootProps }) {
5
+ const getColor = useGetColor()
6
+ let props = useMergeThemeComponent('Icon', rootProps)
7
+
8
+ // props = pipe(
9
+ // useSizeModifier, //
10
+ // usePositionModifier,
11
+ // )(props)
12
+
13
+ return <AbsIcon className="neko-icon" name={name} color={getColor(color || 'text')} {...props} />
14
+ }
@@ -0,0 +1,32 @@
1
+ import { Text } from '../text/Text'
2
+ import { View } from '../structure/View'
3
+ import { moveScaleDown } from '../theme/helpers/sizeScale'
4
+ import { useFullColorModifier } from '../modifiers/fullColor.js'
5
+ import { useMergeThemeComponent } from '../theme/ThemeHandler'
6
+
7
+ export function Tag(rootProps) {
8
+ let { label, style, textProps, size = 'md', ...props } = useMergeThemeComponent('Button', rootProps)
9
+ const oneSizeDown = moveScaleDown(size, 1)
10
+ const twoSizeDown = moveScaleDown(size, 2)
11
+ const threeSizeDown = moveScaleDown(size, 3)
12
+ const defaultProps = {
13
+ paddingH: twoSizeDown,
14
+ padding: threeSizeDown,
15
+ outline: true,
16
+ br: threeSizeDown,
17
+ borderWidth: 1,
18
+ color: 'primary',
19
+ center: true,
20
+ }
21
+ const [fontColor, formattedProps] = useFullColorModifier({ ...defaultProps, ...props, style })
22
+
23
+ return (
24
+ <View className="neko-tag" row>
25
+ <View className="neko-tag-inner" {...formattedProps}>
26
+ <Text strong center color={fontColor} size={oneSizeDown} {...textProps}>
27
+ {label}
28
+ </Text>
29
+ </View>
30
+ </View>
31
+ )
32
+ }
@@ -0,0 +1,2 @@
1
+ export * from './Tag'
2
+ export * from './Icon'
@@ -0,0 +1,36 @@
1
+ import { pipe } from 'ramda'
2
+
3
+ import { AbsView } from '../abstractions/View'
4
+ import { useBackgroundModifier } from '../modifiers/background'
5
+ import { useBorderModifier } from '../modifiers/border'
6
+ import { useFlexModifier } from '../modifiers/flex'
7
+ import { useFlexWrapperModifier } from '../modifiers/flexWrapper'
8
+ import { useMarginModifier } from '../modifiers/margin'
9
+ import { useMergeThemeComponent } from '../theme/ThemeHandler'
10
+ import { usePaddingModifier } from '../modifiers/padding'
11
+ import { usePositionModifier } from '../modifiers/position'
12
+ import { useShadowModifier } from '../modifiers/shadow'
13
+ import { useSizeModifier } from '../modifiers/size'
14
+
15
+ export function Card({ children, ...rootProps }) {
16
+ let props = useMergeThemeComponent('Card', rootProps)
17
+ const defaultProps = { padding: 'md', br: 'xlg', bg: 'overlayBG' }
18
+
19
+ props = pipe(
20
+ useSizeModifier, //
21
+ usePositionModifier,
22
+ usePaddingModifier,
23
+ useMarginModifier,
24
+ useFlexWrapperModifier,
25
+ useFlexModifier,
26
+ useBackgroundModifier,
27
+ useBorderModifier,
28
+ useShadowModifier
29
+ )({ ...defaultProps, ...props })
30
+
31
+ return (
32
+ <AbsView className="neko-card" {...props}>
33
+ {children}
34
+ </AbsView>
35
+ )
36
+ }
@@ -1,22 +1,34 @@
1
1
  import { pipe } from 'ramda'
2
2
 
3
3
  import { AbsView } from '../abstractions/View'
4
+ import { useBackgroundModifier } from '../modifiers/background'
5
+ import { useBorderModifier } from '../modifiers/border'
4
6
  import { useFlexModifier } from '../modifiers/flex'
5
7
  import { useFlexWrapperModifier } from '../modifiers/flexWrapper'
6
8
  import { useMarginModifier } from '../modifiers/margin'
9
+ import { useMergeThemeComponent } from '../theme/ThemeHandler'
7
10
  import { usePaddingModifier } from '../modifiers/padding'
8
11
  import { usePositionModifier } from '../modifiers/position'
12
+ import { useShadowModifier } from '../modifiers/shadow'
9
13
  import { useSizeModifier } from '../modifiers/size'
10
14
 
11
- export function View({ children, ...props }) {
15
+ export function View({ children, ...rootProps }) {
16
+ let props = useMergeThemeComponent('View', rootProps)
12
17
  props = pipe(
13
18
  useSizeModifier, //
14
19
  usePositionModifier,
15
20
  usePaddingModifier,
16
21
  useMarginModifier,
17
22
  useFlexWrapperModifier,
18
- useFlexModifier
23
+ useFlexModifier,
24
+ useBackgroundModifier,
25
+ useBorderModifier,
26
+ useShadowModifier
19
27
  )(props)
20
28
 
21
- return <AbsView {...props}>{children}</AbsView>
29
+ return (
30
+ <AbsView className="neko-view" {...props}>
31
+ {children}
32
+ </AbsView>
33
+ )
22
34
  }
@@ -1 +1,2 @@
1
1
  export * from './View'
2
+ export * from './Card'
@@ -0,0 +1,20 @@
1
+ import { pipe } from 'ramda'
2
+
3
+ import { AbsText } from '../abstractions/Text'
4
+ import { useFlexModifier } from '../modifiers/flex'
5
+ import { useMarginModifier } from '../modifiers/margin'
6
+ import { usePaddingModifier } from '../modifiers/padding'
7
+ import { useSizeModifier } from '../modifiers/size'
8
+ import { useTextModifier } from '../modifiers/text'
9
+
10
+ export function Text({ children, ...props }) {
11
+ props = pipe(
12
+ useSizeModifier, //
13
+ usePaddingModifier,
14
+ useMarginModifier,
15
+ useFlexModifier,
16
+ useTextModifier
17
+ )(props)
18
+
19
+ return <AbsText {...props}>{children}</AbsText>
20
+ }
@@ -0,0 +1 @@
1
+ export * from './Text'
@@ -1,10 +1,64 @@
1
+ import { mergeDeepRight } from 'ramda'
1
2
  import React from 'react'
2
3
 
4
+ import { DEFAULT_LIGHT_THEME } from './default/lightTheme'
5
+ import { DEFAULT_THEMES } from './default/themes'
6
+ import { useFormattedTheme } from './format/formatTheme'
7
+
3
8
  const ThemeContext = React.createContext(null)
4
9
  export const useThemeHandler = () => React.useContext(ThemeContext) || {}
10
+ export const useTheme = () => useThemeHandler().theme || DEFAULT_LIGHT_THEME
11
+
12
+ export const useColors = () => useTheme().colors || {}
13
+ const getColor = (colors, key) => colors[key] || key
14
+ export const useGetColor = () => {
15
+ const colors = useColors()
16
+ return (key) => getColor(colors, key)
17
+ }
18
+
19
+ export const useSpaces = () => useTheme().spaces || {}
20
+ const getSpace = (spaces, key) => spaces[key] || key
21
+ export const useGetSpace = () => {
22
+ const spaces = useSpaces()
23
+ return (key) => getSpace(spaces, key)
24
+ }
25
+
26
+ export const useRadius = () => useTheme().radius || {}
27
+ const getRadius = (radius, key) => radius[key] || key
28
+ export const useGetRadius = () => {
29
+ const radius = useRadius()
30
+ return (key) => getRadius(radius, key)
31
+ }
32
+
33
+ export const useTexts = () => useTheme().texts || {}
34
+
35
+ export function mergePreset(presets, key, props, defaultKey) {
36
+ if (!key) return props
37
+ const preset = presets[key] || presets[defaultKey]
38
+ return { ...props, ...preset }
39
+ }
40
+
41
+ export const useElementHeights = () => useTheme().elementHeights || {}
42
+ const getElementHeight = (elementHeights, key) => elementHeights[key] || key
43
+ export const useGetElementHeight = () => {
44
+ const elementHeights = useElementHeights()
45
+ return (key) => getElementHeight(elementHeights, key)
46
+ }
47
+
48
+ export const useThemeComponents = () => useTheme().components || {}
49
+ export function useThemeComponent(name) {
50
+ const components = useThemeComponents()
51
+ return components[name] || {}
52
+ }
53
+ export function useMergeThemeComponent(name, props) {
54
+ const themeProps = useThemeComponent(name)
55
+ return mergeDeepRight(themeProps, props)
56
+ }
5
57
 
6
- export function ThemeHandler({ themes, children }) {
7
- const value = {}
58
+ export function ThemeHandler({ themes, initTheme, children }) {
59
+ const [activeThemeKey, setActiveThemeKey] = React.useState(initTheme || 'light')
60
+ const theme = useFormattedTheme(themes, activeThemeKey)
61
+ const value = { theme, themes, activeThemeKey, setActiveThemeKey }
8
62
 
9
63
  return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>
10
64
  }
@@ -0,0 +1,65 @@
1
+ export const BASE_THEME = {
2
+ spaces: {
3
+ xxxsm: 1,
4
+ xxsm: 3,
5
+ xsm: 5,
6
+ sm: 10,
7
+ md: 15,
8
+ lg: 20,
9
+ xlg: 30,
10
+ xxlg: 40,
11
+ xxxlg: 50,
12
+ },
13
+
14
+ radius: {
15
+ xxxsm: 4,
16
+ xxsm: 5,
17
+ xsm: 5,
18
+ sm: 7,
19
+ md: 8,
20
+ lg: 10,
21
+ xlg: 12,
22
+ xxlg: 15,
23
+ xxxlg: 18,
24
+ },
25
+
26
+ // Buttons, inputs, tags
27
+ elementHeights: {
28
+ xsm: 20,
29
+ sm: 30,
30
+ md: 35,
31
+ lg: 50,
32
+ xlg: 60,
33
+ },
34
+
35
+ texts: {
36
+ h1: {
37
+ fontSize: 32,
38
+ strong: true,
39
+ },
40
+ h2: {
41
+ fontSize: 26,
42
+ strong: true,
43
+ },
44
+ h3: {
45
+ fontSize: 22,
46
+ strong: true,
47
+ },
48
+ h4: {
49
+ fontSize: 18,
50
+ strong: true,
51
+ },
52
+ h5: {
53
+ fontSize: 16,
54
+ strong: true,
55
+ },
56
+ h6: {
57
+ fontSize: 14,
58
+ strong: true,
59
+ },
60
+ p: { fontSize: 14 },
61
+ sm: { fontSize: 12 },
62
+ xsm: { fontSize: 10 },
63
+ xxsm: { fontSize: 8 },
64
+ },
65
+ }