@sanity-labs/ui-poc 0.0.1-alpha.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 (81) hide show
  1. package/dist/components.css +9 -0
  2. package/dist/index.d.ts +203 -0
  3. package/dist/index.js +290 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/styles.css +8044 -0
  6. package/dist/utilities.css +8032 -0
  7. package/package.json +89 -0
  8. package/src/components/box/Box.tsx +30 -0
  9. package/src/components/box/box.props.ts +15 -0
  10. package/src/components/flex/Flex.tsx +31 -0
  11. package/src/components/flex/flex.props.ts +19 -0
  12. package/src/components/grid/Grid.tsx +31 -0
  13. package/src/components/grid/grid.props.ts +19 -0
  14. package/src/components/index.css +0 -0
  15. package/src/components/text/Text.tsx +43 -0
  16. package/src/components/text/text.props.ts +15 -0
  17. package/src/css/global.css +103 -0
  18. package/src/css/index.css +6 -0
  19. package/src/css/utilities/dynamic/flex-child.css +5 -0
  20. package/src/css/utilities/dynamic/grid-child.css +8 -0
  21. package/src/css/utilities/dynamic/grid-parent.css +6 -0
  22. package/src/css/utilities/dynamic/height.css +5 -0
  23. package/src/css/utilities/dynamic/index.css +7 -0
  24. package/src/css/utilities/dynamic/line-clamp.css +6 -0
  25. package/src/css/utilities/dynamic/width.css +5 -0
  26. package/src/css/utilities/dynamic/z-index.css +3 -0
  27. package/src/css/utilities/generic/border.css +11 -0
  28. package/src/css/utilities/generic/display.css +13 -0
  29. package/src/css/utilities/generic/flex.css +24 -0
  30. package/src/css/utilities/generic/grid.css +7 -0
  31. package/src/css/utilities/generic/index.css +10 -0
  32. package/src/css/utilities/generic/overflow.css +19 -0
  33. package/src/css/utilities/generic/position.css +7 -0
  34. package/src/css/utilities/generic/text-align.css +5 -0
  35. package/src/css/utilities/generic/text-muted.css +2 -0
  36. package/src/css/utilities/generic/text-trim.css +38 -0
  37. package/src/css/utilities/generic/tone.css +34 -0
  38. package/src/css/utilities/tokenized/color.css +223 -0
  39. package/src/css/utilities/tokenized/container.css +8 -0
  40. package/src/css/utilities/tokenized/fontFamily.css +2 -0
  41. package/src/css/utilities/tokenized/fontWeight.css +4 -0
  42. package/src/css/utilities/tokenized/gap.css +34 -0
  43. package/src/css/utilities/tokenized/index.css +9 -0
  44. package/src/css/utilities/tokenized/inset.css +56 -0
  45. package/src/css/utilities/tokenized/margin.css +92 -0
  46. package/src/css/utilities/tokenized/padding.css +85 -0
  47. package/src/css/utilities/tokenized/radius.css +8 -0
  48. package/src/css/utilities/tokenized/shadow.css +6 -0
  49. package/src/css/utilities/tokenized/typography.css +31 -0
  50. package/src/index.css +2 -0
  51. package/src/index.ts +1 -0
  52. package/src/props/border.ts +51 -0
  53. package/src/props/flexChild.ts +29 -0
  54. package/src/props/flexParent.ts +46 -0
  55. package/src/props/gap.ts +30 -0
  56. package/src/props/gridChild.ts +50 -0
  57. package/src/props/gridParent.ts +44 -0
  58. package/src/props/height.ts +29 -0
  59. package/src/props/layout.ts +37 -0
  60. package/src/props/margin.ts +58 -0
  61. package/src/props/overflow.ts +30 -0
  62. package/src/props/padding.ts +58 -0
  63. package/src/props/position.ts +59 -0
  64. package/src/props/tone.ts +16 -0
  65. package/src/props/typography.ts +46 -0
  66. package/src/props/width.ts +29 -0
  67. package/src/types/Display.ts +8 -0
  68. package/src/types/Flex.ts +18 -0
  69. package/src/types/FontWeight.ts +2 -0
  70. package/src/types/Grid.ts +2 -0
  71. package/src/types/Overflow.ts +2 -0
  72. package/src/types/Position.ts +2 -0
  73. package/src/types/PropDef.ts +25 -0
  74. package/src/types/Radius.ts +2 -0
  75. package/src/types/Responsive.ts +10 -0
  76. package/src/types/Space.ts +5 -0
  77. package/src/types/Text.ts +2 -0
  78. package/src/types/TextAlign.ts +2 -0
  79. package/src/types/Tone.ts +2 -0
  80. package/src/utils/getProps.test.ts +103 -0
  81. package/src/utils/getProps.ts +74 -0
@@ -0,0 +1,103 @@
1
+ import {describe, expect, it} from 'vitest'
2
+
3
+ import {layoutProps} from '../props/layout'
4
+ import {getProps} from './getProps'
5
+
6
+ describe('getProps', () => {
7
+ it('generates className based on an union', () => {
8
+ const result = getProps({padding: 1}, layoutProps)
9
+ expect(result.className).toBe('sui-padding-1')
10
+ expect(result.style).toEqual({})
11
+ })
12
+
13
+ it('does not generate className based on union if value is unsupported', () => {
14
+ const result = getProps({padding: 10}, layoutProps)
15
+ expect(result.className).toBe('')
16
+ expect(result.style).toEqual({})
17
+ })
18
+
19
+ it('merges existing className', () => {
20
+ const result = getProps({className: 'test', padding: 1}, layoutProps)
21
+ expect(result.className).toBe('test sui-padding-1')
22
+ expect(result.style).toEqual({})
23
+ })
24
+
25
+ it('generates className and style based on a string', () => {
26
+ const result = getProps({width: '100px'}, layoutProps)
27
+ expect(result.className).toBe('sui-width')
28
+ expect(result.style).toEqual({'--width': '100px'})
29
+ })
30
+
31
+ it('merges existing style', () => {
32
+ const result = getProps({width: '100px', style: {display: 'block'}}, layoutProps)
33
+ expect(result.className).toBe('sui-width')
34
+ expect(result.style).toEqual({'--width': '100px', 'display': 'block'})
35
+ })
36
+
37
+ it('generates className based on a boolean', () => {
38
+ const result = getProps({border: true}, layoutProps)
39
+ expect(result.className).toBe('sui-border')
40
+ expect(result.style).toEqual({})
41
+ })
42
+
43
+ it('generates className based on a number', () => {
44
+ const result = getProps({flexGrow: 1.5}, layoutProps)
45
+ expect(result.className).toBe('sui-flex-grow')
46
+ expect(result.style).toEqual({'--flex-grow': 1.5})
47
+ })
48
+
49
+ it('generates multiple classNames', () => {
50
+ const result = getProps({border: true, padding: 1}, layoutProps)
51
+ expect(result.className).toBe('sui-border sui-padding-1')
52
+ expect(result.style).toEqual({})
53
+ })
54
+
55
+ it('preserves non-styling props', () => {
56
+ const result = getProps({padding: 1, as: 'div'}, layoutProps)
57
+ expect(result.className).toBe('sui-padding-1')
58
+ expect(result.style).toEqual({})
59
+ expect(result.as).toEqual('div')
60
+ })
61
+
62
+ it('generates responsive className based on unions', () => {
63
+ const result = getProps({padding: [1, 2, 3]}, layoutProps)
64
+ expect(result.className).toBe('sui-padding-1 sui-padding-2-bp-1 sui-padding-3-bp-2')
65
+ expect(result.style).toEqual({})
66
+ })
67
+
68
+ it('generates responsive className and style based on strings', () => {
69
+ const result = getProps({width: ['100px', '200px', '300px']}, layoutProps)
70
+ expect(result.className).toBe('sui-width sui-width-bp-1 sui-width-bp-2')
71
+ expect(result.style).toEqual({
72
+ '--width': '100px',
73
+ '--width-bp-1': '200px',
74
+ '--width-bp-2': '300px',
75
+ })
76
+ })
77
+
78
+ it('generates responsive className based on booleans', () => {
79
+ const result = getProps({border: [true, false, true]}, layoutProps)
80
+ expect(result.className).toBe('sui-border sui-border-none-bp-1 sui-border-bp-2')
81
+ expect(result.style).toEqual({})
82
+ })
83
+
84
+ it('does not generate responsive className with more values than breakpoints', () => {
85
+ const result = getProps({padding: [1, 2, 3, 4, 5, 6, 7, 8]}, layoutProps)
86
+ expect(result.className).toBe(
87
+ 'sui-padding-1 sui-padding-2-bp-1 sui-padding-3-bp-2 sui-padding-4-bp-3 sui-padding-5-bp-4 sui-padding-6-bp-5 sui-padding-7-bp-6',
88
+ )
89
+ expect(result.style).toEqual({})
90
+ })
91
+
92
+ it('generates responsive className with undefined values', () => {
93
+ const result = getProps({padding: [1, 2, undefined, 3]}, layoutProps)
94
+ expect(result.className).toBe('sui-padding-1 sui-padding-2-bp-1 sui-padding-3-bp-3')
95
+ expect(result.style).toEqual({})
96
+ })
97
+
98
+ it('generates responsive className without unsupported values', () => {
99
+ const result = getProps({padding: [1, 2, 10, 3]}, layoutProps)
100
+ expect(result.className).toBe('sui-padding-1 sui-padding-2-bp-1 sui-padding-3-bp-3')
101
+ expect(result.style).toEqual({})
102
+ })
103
+ })
@@ -0,0 +1,74 @@
1
+ import classNames from 'classnames'
2
+
3
+ import {type PropDef} from '../types/PropDef'
4
+
5
+ const PREFIX = 'sui'
6
+ const BREAKPOINTS_LENGTH = 7
7
+
8
+ interface ComponentProps {
9
+ className?: string
10
+ style?: React.CSSProperties
11
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
12
+ [key: string]: any
13
+ }
14
+
15
+ export function getProps<P extends ComponentProps, T extends Record<string, PropDef>>(
16
+ componentProps?: P,
17
+ propDefs?: T,
18
+ ): ComponentProps {
19
+ let className = componentProps?.className || ''
20
+ let style = componentProps?.style || {}
21
+ const restProps: ComponentProps = {}
22
+
23
+ for (const key in componentProps) {
24
+ if (!propDefs?.[key] || !propDefs?.[key].className) {
25
+ restProps[key] = componentProps[key]
26
+ continue
27
+ }
28
+
29
+ if (Array.isArray(componentProps[key])) {
30
+ for (
31
+ let i = 0, len = Math.min(componentProps[key].length, BREAKPOINTS_LENGTH);
32
+ i < len;
33
+ i++
34
+ ) {
35
+ className = classNames(className, getClassName(componentProps[key][i], propDefs[key], i))
36
+ style = {...style, ...getStyle(componentProps[key][i], propDefs[key], i)}
37
+ }
38
+ } else {
39
+ className = classNames(className, getClassName(componentProps[key], propDefs[key]))
40
+ style = {...style, ...getStyle(componentProps[key], propDefs[key])}
41
+ }
42
+ }
43
+
44
+ return {...restProps, className, style}
45
+ }
46
+
47
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
48
+ function getClassName(prop: any, propDef: PropDef, bp?: number) {
49
+ if (propDef.type === 'union' && propDef.values?.includes(prop)) {
50
+ /* Note: This may need updating depending on the final CSS classname formatting */
51
+ return `${PREFIX}-${propDef.className}${typeof prop === 'string' ? `-${prop}` : prop}${bp ? `-bp-${bp}` : ''}`
52
+ }
53
+
54
+ if (propDef.type === 'string' || propDef.type === 'number') {
55
+ return `${PREFIX}-${propDef.className}${bp ? `-bp-${bp}` : ''}`
56
+ }
57
+
58
+ if (propDef.type === 'boolean') {
59
+ return `${PREFIX}-${prop ? propDef.className : propDef.inverse}${bp ? `-bp-${bp}` : ''}`
60
+ }
61
+
62
+ return ''
63
+ }
64
+
65
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
66
+ function getStyle(prop: any, propDef: PropDef, bp?: number) {
67
+ if (propDef.type === 'string' || propDef.type === 'number') {
68
+ return {
69
+ [`${propDef.variable}${bp ? `-bp-${bp}` : ''}`]: prop,
70
+ }
71
+ }
72
+
73
+ return {}
74
+ }