@charcoal-ui/styled 2.3.0 → 2.5.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 (57) hide show
  1. package/dist/builders/border.d.ts +10 -0
  2. package/dist/builders/border.d.ts.map +1 -0
  3. package/dist/builders/borderRadius.d.ts +7 -0
  4. package/dist/builders/borderRadius.d.ts.map +1 -0
  5. package/dist/builders/colors.d.ts +13 -0
  6. package/dist/builders/colors.d.ts.map +1 -0
  7. package/dist/builders/elementEffect.d.ts +7 -0
  8. package/dist/builders/elementEffect.d.ts.map +1 -0
  9. package/dist/builders/o.d.ts +115 -0
  10. package/dist/builders/o.d.ts.map +1 -0
  11. package/dist/builders/outline.d.ts +10 -0
  12. package/dist/builders/outline.d.ts.map +1 -0
  13. package/dist/builders/size.d.ts +23 -0
  14. package/dist/builders/size.d.ts.map +1 -0
  15. package/dist/builders/spacing.d.ts +15 -0
  16. package/dist/builders/spacing.d.ts.map +1 -0
  17. package/dist/builders/transition.d.ts +7 -0
  18. package/dist/builders/transition.d.ts.map +1 -0
  19. package/dist/builders/typography.d.ts +11 -0
  20. package/dist/builders/typography.d.ts.map +1 -0
  21. package/dist/{lib.d.ts → factories/lib.d.ts} +13 -14
  22. package/dist/factories/lib.d.ts.map +1 -0
  23. package/dist/index.cjs +765 -643
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.ts +91 -30
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.modern.js +555 -393
  28. package/dist/index.modern.js.map +1 -1
  29. package/dist/index.module.js +765 -643
  30. package/dist/index.module.js.map +1 -1
  31. package/dist/index.story.d.ts +1 -0
  32. package/dist/index.story.d.ts.map +1 -1
  33. package/dist/index.test.d.ts +2 -0
  34. package/dist/index.test.d.ts.map +1 -0
  35. package/dist/internals/index.d.ts +42 -0
  36. package/dist/internals/index.d.ts.map +1 -0
  37. package/dist/util.d.ts +36 -2
  38. package/dist/util.d.ts.map +1 -1
  39. package/package.json +8 -5
  40. package/src/__snapshots__/index.test.tsx.snap +768 -0
  41. package/src/builders/border.ts +63 -0
  42. package/src/builders/borderRadius.ts +32 -0
  43. package/src/builders/colors.ts +198 -0
  44. package/src/builders/elementEffect.ts +54 -0
  45. package/src/builders/o.ts +43 -0
  46. package/src/builders/outline.ts +79 -0
  47. package/src/builders/size.ts +61 -0
  48. package/src/builders/spacing.ts +113 -0
  49. package/src/builders/transition.ts +32 -0
  50. package/src/builders/typography.ts +97 -0
  51. package/src/{lib.ts → factories/lib.ts} +30 -25
  52. package/src/index.story.tsx +2 -2
  53. package/src/index.test.tsx +24 -0
  54. package/src/index.ts +47 -696
  55. package/src/internals/index.ts +84 -0
  56. package/src/util.ts +46 -3
  57. package/dist/lib.d.ts.map +0 -1
@@ -0,0 +1,63 @@
1
+ import { CharcoalAbstractTheme } from '@charcoal-ui/theme'
2
+ import { CSSObject } from 'styled-components'
3
+ import { keyof } from '../util'
4
+ import { Internal, createInternal } from '../internals'
5
+ import {
6
+ defineConstantProperties,
7
+ defineProperties,
8
+ definePropertyChains,
9
+ } from '../factories/lib'
10
+
11
+ export const borderDirections = ['top', 'right', 'bottom', 'left'] as const
12
+ type BorderDirection = typeof borderDirections[number]
13
+
14
+ function borderProperty(direction: BorderDirection) {
15
+ return `border-${direction}`
16
+ }
17
+
18
+ function borderShorthand(color: string) {
19
+ return `solid 1px ${color}`
20
+ }
21
+
22
+ export const createBorderCss =
23
+ <T extends CharcoalAbstractTheme>(theme: T) =>
24
+ (
25
+ variant: keyof T['border'],
26
+ directions: readonly BorderDirection[]
27
+ ): Internal => {
28
+ const all = directions.length === 0
29
+ const value = borderShorthand(theme.border[variant].color)
30
+
31
+ return createInternal({
32
+ toCSS() {
33
+ return {
34
+ ...(all
35
+ ? { border: value }
36
+ : directions.reduce<CSSObject>(
37
+ (acc, direction) => ({
38
+ ...acc,
39
+ [borderProperty(direction)]: value,
40
+ }),
41
+ {}
42
+ )),
43
+ }
44
+ },
45
+ })
46
+ }
47
+
48
+ export default function border<T extends CharcoalAbstractTheme>(theme: T) {
49
+ const borderTypes = keyof<T['border']>(theme.border)
50
+
51
+ const borderCss = createBorderCss(theme)
52
+ const borderObject = defineConstantProperties(
53
+ {},
54
+ {
55
+ border: defineProperties({}, borderTypes, (variant) =>
56
+ definePropertyChains(borderDirections, (modifiers) =>
57
+ borderCss(variant, modifiers)
58
+ )
59
+ ),
60
+ }
61
+ )
62
+ return borderObject
63
+ }
@@ -0,0 +1,32 @@
1
+ import { CharcoalAbstractTheme } from '@charcoal-ui/theme'
2
+ import { px } from '@charcoal-ui/utils'
3
+ import { Internal, createInternal } from '../internals'
4
+ import { defineConstantProperties } from '../factories/lib'
5
+
6
+ export const createBorderRadiusCss =
7
+ <T extends CharcoalAbstractTheme>(theme: T) =>
8
+ (size: keyof T['borderRadius']): Internal => {
9
+ return createInternal({
10
+ toCSS() {
11
+ return {
12
+ borderRadius: px(theme.borderRadius[size]),
13
+ }
14
+ },
15
+ })
16
+ }
17
+
18
+ export default function borderRadius<T extends CharcoalAbstractTheme>(
19
+ theme: T
20
+ ) {
21
+ // 角丸
22
+ const borderRadiusCss = createBorderRadiusCss(theme)
23
+ const borderRadiusObject = defineConstantProperties(
24
+ {},
25
+ {
26
+ borderRadius: (radius: keyof T['borderRadius']) =>
27
+ borderRadiusCss(radius),
28
+ }
29
+ )
30
+
31
+ return borderRadiusObject
32
+ }
@@ -0,0 +1,198 @@
1
+ import { CharcoalAbstractTheme } from '@charcoal-ui/theme'
2
+ import {
3
+ applyEffect,
4
+ applyEffectToGradient,
5
+ customPropertyToken,
6
+ dur,
7
+ gradient,
8
+ GradientDirection,
9
+ } from '@charcoal-ui/utils'
10
+ import { CSSObject } from 'styled-components'
11
+ import warning from 'warning'
12
+ import {
13
+ keyof,
14
+ objectAssign,
15
+ isSupportedEffect,
16
+ onEffectPseudo,
17
+ variable,
18
+ } from '../util'
19
+ import {
20
+ createInternal,
21
+ Internal,
22
+ Context,
23
+ shouldCancelHalfLeading,
24
+ } from '../internals'
25
+ import {
26
+ defineConstantProperties,
27
+ defineProperties,
28
+ definePropertyChains,
29
+ } from '../factories/lib'
30
+ import { TRANSITION_DURATION } from './transition'
31
+
32
+ const colorProperties = ['bg', 'font'] as const
33
+ export type ColorProperty = typeof colorProperties[number]
34
+
35
+ function targetProperty(target: ColorProperty) {
36
+ return target === 'bg' ? 'background-color' : 'color'
37
+ }
38
+
39
+ export const createColorCss =
40
+ <T extends CharcoalAbstractTheme>(_theme: T) =>
41
+ (
42
+ target: ColorProperty,
43
+ color: keyof T['color'],
44
+ effects: readonly (keyof T['effect'])[] = []
45
+ ): Internal => {
46
+ function toCSS() {
47
+ return {
48
+ [targetProperty(target)]: variable(
49
+ customPropertyToken(color.toString())
50
+ ),
51
+ ...effects.filter(isSupportedEffect).reduce<CSSObject>(
52
+ (acc, effect) => ({
53
+ ...acc,
54
+ ...onEffectPseudo(effect, {
55
+ [targetProperty(target)]: variable(
56
+ customPropertyToken(color.toString(), [effect])
57
+ ),
58
+ }),
59
+ }),
60
+ {}
61
+ ),
62
+ }
63
+ }
64
+
65
+ return createInternal({
66
+ toCSS,
67
+ context:
68
+ effects.length > 0
69
+ ? target === 'font'
70
+ ? {
71
+ colorTransition: true,
72
+ }
73
+ : {
74
+ backgroundColorTransition: true,
75
+ }
76
+ : {},
77
+ })
78
+ }
79
+
80
+ export const createGradientColorCss =
81
+ <T extends CharcoalAbstractTheme>(theme: T) =>
82
+ (
83
+ color: keyof T['gradientColor'],
84
+ effects: readonly (keyof T['effect'])[] = [],
85
+ direction: GradientDirection
86
+ ): Internal => {
87
+ const toLinearGradient = gradient(direction)
88
+
89
+ function toCSS(context: Context): CSSObject {
90
+ const optimized = !shouldCancelHalfLeading(context)
91
+ const duration = dur(TRANSITION_DURATION)
92
+
93
+ if (optimized && effects.length > 0) {
94
+ return {
95
+ position: 'relative',
96
+ zIndex: 0,
97
+ overflow: 'hidden',
98
+ ...effects.filter(isSupportedEffect).reduce<CSSObject>(
99
+ (acc, effect) => ({
100
+ ...acc,
101
+ '&::before': {
102
+ zIndex: -1,
103
+ ...overlayElement,
104
+ transition: `${duration} background-color`,
105
+ },
106
+ '&::after': {
107
+ zIndex: -2,
108
+ ...overlayElement,
109
+ ...toLinearGradient(theme.gradientColor[color]),
110
+ },
111
+ ...onEffectPseudo(effect, {
112
+ '&::before': {
113
+ backgroundColor: applyEffect(
114
+ null,
115
+ theme.effect[effect] ?? []
116
+ ),
117
+ },
118
+ }),
119
+ }),
120
+ {}
121
+ ),
122
+ }
123
+ }
124
+
125
+ warning(
126
+ effects.length === 0,
127
+ // eslint-disable-next-line max-len
128
+ `'Transition' will not be applied. You can get around this by specifying 'preserveHalfLeading' or both 'padding' and 'typograpy'.`
129
+ )
130
+
131
+ return {
132
+ ...toLinearGradient(theme.gradientColor[color]),
133
+ ...effects.filter(isSupportedEffect).reduce<CSSObject>(
134
+ (acc, effect) => ({
135
+ ...acc,
136
+ ...onEffectPseudo(effect, {
137
+ ...toLinearGradient(
138
+ applyEffectToGradient(theme.effect[effect] ?? [])(
139
+ theme.gradientColor[color]
140
+ )
141
+ ),
142
+ }),
143
+ }),
144
+ {}
145
+ ),
146
+ }
147
+ }
148
+
149
+ return createInternal({ toCSS })
150
+ }
151
+
152
+ const overlayElement: CSSObject = {
153
+ content: "''",
154
+ display: 'block',
155
+ position: 'absolute',
156
+ width: '100%',
157
+ height: '100%',
158
+ top: 0,
159
+ left: 0,
160
+ }
161
+
162
+ export default function colors<T extends CharcoalAbstractTheme>(theme: T) {
163
+ const colors = keyof<T['color']>(theme.color)
164
+ const effects = keyof<T['effect']>(theme.effect)
165
+
166
+ // 色
167
+ const gradientColors = keyof<T['gradientColor']>(theme.gradientColor)
168
+ const colorCss = createColorCss(theme)
169
+ const gradientColorCss = createGradientColorCss(theme)
170
+
171
+ const colorObject = defineConstantProperties(
172
+ {},
173
+ {
174
+ bg: objectAssign(
175
+ defineProperties({}, colors, (color) =>
176
+ definePropertyChains(effects, (modifiers) =>
177
+ colorCss('bg', color, modifiers)
178
+ )
179
+ ),
180
+ defineProperties(
181
+ {},
182
+ gradientColors,
183
+ (color) => (direction: GradientDirection) =>
184
+ definePropertyChains(effects, (modifiers) =>
185
+ gradientColorCss(color, modifiers, direction)
186
+ )
187
+ )
188
+ ),
189
+ font: defineProperties({}, colors, (color) =>
190
+ definePropertyChains(effects, (modifiers) =>
191
+ colorCss('font', color, modifiers)
192
+ )
193
+ ),
194
+ }
195
+ )
196
+
197
+ return colorObject
198
+ }
@@ -0,0 +1,54 @@
1
+ import { CharcoalAbstractTheme, EffectType } from '@charcoal-ui/theme'
2
+ import { CSSObject } from 'styled-components'
3
+ import {
4
+ isSupportedEffect,
5
+ keyof,
6
+ onEffectPseudo,
7
+ ReadonlyArrayConstructor,
8
+ unreachable,
9
+ } from '../util'
10
+ import { Internal, createInternal } from '../internals'
11
+ import { definePropertyChains } from '../factories/lib'
12
+
13
+ export const createElementEffectCss =
14
+ <
15
+ T extends CharcoalAbstractTheme,
16
+ TElementEffect extends T['elementEffect']
17
+ >(theme: {
18
+ elementEffect: TElementEffect
19
+ }) =>
20
+ (effects: readonly (keyof TElementEffect)[] = []): Internal =>
21
+ createInternal({
22
+ toCSS() {
23
+ return effects.filter(isSupportedEffect).reduce<CSSObject>(
24
+ (acc, effect) => ({
25
+ ...acc,
26
+ ...onEffectPseudo(effect, {
27
+ opacity:
28
+ !(Array as ReadonlyArrayConstructor).isArray(
29
+ theme.elementEffect[effect]
30
+ ) && theme.elementEffect[effect]?.type === 'opacity'
31
+ ? theme.elementEffect[effect]?.opacity
32
+ : unreachable(),
33
+ }),
34
+ }),
35
+ {}
36
+ )
37
+ },
38
+ })
39
+
40
+ export default function elementEffect<T extends CharcoalAbstractTheme>(
41
+ theme: T
42
+ ) {
43
+ const effectTypes = keyof<T['elementEffect']>(
44
+ theme.elementEffect
45
+ ) as EffectType[]
46
+
47
+ // 要素へのエフェクト (etc: 透過)
48
+ const elementEffectCss = createElementEffectCss(theme)
49
+ const elementEffectObject = definePropertyChains(effectTypes, (modifiers) =>
50
+ elementEffectCss(modifiers)
51
+ )
52
+
53
+ return elementEffectObject
54
+ }
@@ -0,0 +1,43 @@
1
+ import { CharcoalAbstractTheme } from '@charcoal-ui/theme'
2
+ import { objectAssign } from '../util'
3
+ import border from './border'
4
+ import borderRadius from './borderRadius'
5
+ import colors from './colors'
6
+ import elementEffect from './elementEffect'
7
+ import outline from './outline'
8
+ import size from './size'
9
+ import spacing from './spacing'
10
+ import typography from './typography'
11
+
12
+ /**
13
+ * `theme(o => [...])` の `o` の部分を構築する
14
+ *
15
+ * @param theme テーマオブジェクト
16
+ * @param DO_NOTHING_IT_IS_JUST_CALLED_FOR_TYPE_INFERENCE 型推論のためだけに使う場合にランタイムコストをゼロにするフラグ
17
+ */
18
+ export default function createO<T extends CharcoalAbstractTheme>(
19
+ theme: {
20
+ // factoryの第二引数に入れ込むものだけ明示的に型変数を展開しておくことで型の具象化を遅延する
21
+ color: T['color']
22
+ gradientColor: T['gradientColor']
23
+ border: T['border']
24
+ outline: T['outline']
25
+ } & Omit<T, 'color' | 'gradientColor' | 'border' | 'outline'>,
26
+ DO_NOTHING_IT_IS_JUST_CALLED_FOR_TYPE_INFERENCE = false
27
+ ) {
28
+ if (DO_NOTHING_IT_IS_JUST_CALLED_FOR_TYPE_INFERENCE) {
29
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
30
+ return {} as never
31
+ }
32
+
33
+ return objectAssign(
34
+ colors(theme),
35
+ typography(theme),
36
+ spacing(theme),
37
+ size(theme),
38
+ elementEffect(theme),
39
+ border(theme),
40
+ borderRadius(theme),
41
+ outline(theme)
42
+ )
43
+ }
@@ -0,0 +1,79 @@
1
+ import { CharcoalAbstractTheme } from '@charcoal-ui/theme'
2
+ import { px, notDisabledSelector } from '@charcoal-ui/utils'
3
+ import { CSSObject } from 'styled-components'
4
+ import { keyof } from '../util'
5
+ import { Internal, createInternal } from '../internals'
6
+ import {
7
+ defineConstantProperties,
8
+ defineProperties,
9
+ definePropertyChains,
10
+ } from '../factories/lib'
11
+
12
+ export const outlineType = ['focus'] as const
13
+ type OutlineType = typeof outlineType[number]
14
+
15
+ const outlineCss = (weight: number, color: string) => ({
16
+ boxShadow: `0 0 0 ${px(weight)} ${color}`,
17
+ })
18
+
19
+ export const createOutlineColorCss =
20
+ <T extends CharcoalAbstractTheme>(theme: T) =>
21
+ (
22
+ variant: keyof T['outline'],
23
+ modifiers: readonly OutlineType[]
24
+ ): Internal => {
25
+ const weight = theme.outline[variant].weight
26
+ const color = theme.outline[variant].color
27
+
28
+ return createInternal({
29
+ toCSS() {
30
+ return modifiers.includes('focus')
31
+ ? onFocus(outlineCss(weight, color))
32
+ : { '&&': { [notDisabledSelector]: outlineCss(weight, color) } }
33
+ },
34
+ context: {
35
+ boxShadowTransition: true,
36
+ },
37
+ })
38
+ }
39
+
40
+ /**
41
+ * @see https://developer.mozilla.org/ja/docs/Web/CSS/:focus-visible#selectively_showing_the_focus_indicator
42
+ */
43
+ const onFocus = (css: CSSObject) => ({
44
+ [notDisabledSelector]: {
45
+ '&:focus, &:active': {
46
+ outline: 'none',
47
+ ...css,
48
+ },
49
+
50
+ '&:focus:not(:focus-visible), &:active:not(:focus-visible)': {
51
+ outline: 'none',
52
+ },
53
+
54
+ '&:focus-visible': {
55
+ outline: 'none',
56
+ ...css,
57
+ },
58
+ },
59
+ })
60
+
61
+ export default function outline<T extends CharcoalAbstractTheme>(theme: T) {
62
+ const outlineCss = createOutlineColorCss(theme)
63
+
64
+ const outlineObject = defineConstantProperties(
65
+ {},
66
+ {
67
+ outline: defineProperties(
68
+ {},
69
+ keyof<T['outline']>(theme.outline),
70
+ (variant) =>
71
+ definePropertyChains(outlineType, (modifiers) =>
72
+ outlineCss(variant, modifiers)
73
+ )
74
+ ),
75
+ }
76
+ )
77
+
78
+ return outlineObject
79
+ }
@@ -0,0 +1,61 @@
1
+ import { columnSystem } from '@charcoal-ui/foundation'
2
+ import { CharcoalAbstractTheme } from '@charcoal-ui/theme'
3
+ import { px } from '@charcoal-ui/utils'
4
+ import { Internal, createInternal } from '../internals'
5
+ import { defineProperties, defineConstantProperties } from '../factories/lib'
6
+
7
+ export const fixedProperties = ['width', 'height'] as const
8
+ type FixedProperty = typeof fixedProperties[number]
9
+
10
+ export const createFixedPxCss =
11
+ <T extends CharcoalAbstractTheme>(theme: T) =>
12
+ (property: FixedProperty, size: keyof T['spacing'] | 'auto'): Internal =>
13
+ createInternal({
14
+ toCSS() {
15
+ return {
16
+ [property]: size === 'auto' ? 'auto' : px(theme.spacing[size]),
17
+ }
18
+ },
19
+ })
20
+
21
+ export const createFixedRelativeCss =
22
+ <T extends CharcoalAbstractTheme>(_theme: T) =>
23
+ (property: FixedProperty, amount: '100%' | 'auto'): Internal =>
24
+ createInternal({
25
+ toCSS() {
26
+ return {
27
+ [property]: amount,
28
+ }
29
+ },
30
+ })
31
+
32
+ export const createFixedColumnCss =
33
+ <T extends CharcoalAbstractTheme>(theme: T) =>
34
+ (property: FixedProperty, span: number): Internal =>
35
+ createInternal({
36
+ toCSS() {
37
+ return {
38
+ [property]: px(
39
+ columnSystem(span, theme.grid.unit.column, theme.grid.unit.gutter)
40
+ ),
41
+ }
42
+ },
43
+ })
44
+
45
+ export default function size<T extends CharcoalAbstractTheme>(theme: T) {
46
+ const fixedPxCss = createFixedPxCss(theme)
47
+ const fixedColumnCss = createFixedColumnCss(theme)
48
+ const fixedRelativeCss = createFixedRelativeCss(theme)
49
+ const fixedObject = defineProperties({}, fixedProperties, (property) =>
50
+ defineConstantProperties(
51
+ {},
52
+ {
53
+ px: (size: keyof T['spacing'] | 'auto') => fixedPxCss(property, size),
54
+ column: (span: number) => fixedColumnCss(property, span),
55
+ auto: fixedRelativeCss(property, 'auto'),
56
+ full: fixedRelativeCss(property, '100%'),
57
+ }
58
+ )
59
+ )
60
+ return fixedObject
61
+ }
@@ -0,0 +1,113 @@
1
+ import { CharcoalAbstractTheme } from '@charcoal-ui/theme'
2
+ import { px } from '@charcoal-ui/utils'
3
+ import { CSSObject } from 'styled-components'
4
+ import { Internal, createInternal, Context } from '../internals'
5
+ import { defineProperties, defineMethodChains } from '../factories/lib'
6
+
7
+ export const spacingProperties = ['margin', 'padding'] as const
8
+ export const spacingDirections = [
9
+ 'top',
10
+ 'right',
11
+ 'bottom',
12
+ 'left',
13
+ 'vertical',
14
+ 'horizontal',
15
+ 'all',
16
+ ] as const
17
+ type SpacingProperty = typeof spacingProperties[number]
18
+ type SpacingDirection = typeof spacingDirections[number]
19
+
20
+ function spacingProperty(
21
+ property: SpacingProperty,
22
+ direction: 'top' | 'right' | 'bottom' | 'left'
23
+ ) {
24
+ return `${property}-${direction}`
25
+ }
26
+
27
+ export const createSpacingCss =
28
+ <T extends CharcoalAbstractTheme>(theme: { spacing: T['spacing'] }) =>
29
+ (
30
+ property: SpacingProperty,
31
+ modifiers: readonly [SpacingDirection, keyof T['spacing'] | 'auto'][]
32
+ ): Internal => {
33
+ const { top, right, bottom, left } = modifiers.reduce(
34
+ (acc, [direction, size]) => {
35
+ if (direction === 'all') {
36
+ acc.top = size
37
+ acc.right = size
38
+ acc.bottom = size
39
+ acc.left = size
40
+ } else if (direction === 'vertical') {
41
+ acc.top = size
42
+ acc.bottom = size
43
+ } else if (direction === 'horizontal') {
44
+ acc.right = size
45
+ acc.left = size
46
+ } else {
47
+ acc[direction] = size
48
+ }
49
+ return acc
50
+ },
51
+ {} as Partial<
52
+ Record<'top' | 'right' | 'bottom' | 'left', keyof T['spacing'] | 'auto'>
53
+ >
54
+ )
55
+
56
+ const hasVerticalPadding =
57
+ property === 'padding' &&
58
+ top !== undefined &&
59
+ bottom !== undefined &&
60
+ top !== 'auto' &&
61
+ bottom !== 'auto'
62
+
63
+ function toCSS({ cancelHalfLeadingPx = 0 }: Context): CSSObject {
64
+ return {
65
+ ...(top !== undefined && {
66
+ [spacingProperty(property, 'top')]:
67
+ top === 'auto'
68
+ ? 'auto'
69
+ : px(
70
+ theme.spacing[top] +
71
+ (hasVerticalPadding ? cancelHalfLeadingPx : 0)
72
+ ),
73
+ }),
74
+ ...(bottom !== undefined && {
75
+ [spacingProperty(property, 'bottom')]:
76
+ bottom === 'auto'
77
+ ? 'auto'
78
+ : px(
79
+ theme.spacing[bottom] +
80
+ (hasVerticalPadding ? cancelHalfLeadingPx : 0)
81
+ ),
82
+ }),
83
+ ...(right !== undefined && {
84
+ [spacingProperty(property, 'right')]:
85
+ right === 'auto' ? 'auto' : px(theme.spacing[right]),
86
+ }),
87
+ ...(left !== undefined && {
88
+ [spacingProperty(property, 'left')]:
89
+ left === 'auto' ? 'auto' : px(theme.spacing[left]),
90
+ }),
91
+ }
92
+ }
93
+
94
+ return createInternal({
95
+ toCSS,
96
+ context: hasVerticalPadding ? { hasVerticalPadding: true } : {},
97
+ })
98
+ }
99
+
100
+ export default function spacing<T extends CharcoalAbstractTheme>(theme: T) {
101
+ const spacingCss = createSpacingCss(theme)
102
+ const spacingObject = defineProperties(
103
+ {},
104
+ spacingProperties,
105
+ (spacingProperty) =>
106
+ defineMethodChains(
107
+ spacingDirections,
108
+ (modifiers) => spacingCss(spacingProperty, modifiers),
109
+ {} as keyof T['spacing'] | 'auto' // 推論のためのメタタイプ
110
+ )
111
+ )
112
+ return spacingObject
113
+ }
@@ -0,0 +1,32 @@
1
+ import { dur } from '@charcoal-ui/utils'
2
+ import { isPresent } from '../util'
3
+ import { Internal, createInternal, Context } from '../internals'
4
+
5
+ // TODO: deprecate
6
+ export const TRANSITION_DURATION = 0.2
7
+
8
+ /**
9
+ * context の状態を元に transition を追加する。必ず一番最後に呼ぶ
10
+ */
11
+ export default function transition(_theme: unknown): Internal {
12
+ const duration = dur(TRANSITION_DURATION)
13
+ const transition = (property: string[]) => ({
14
+ transition: property.map((v) => `${duration} ${v}`).join(', '),
15
+ })
16
+
17
+ function toCSS({
18
+ colorTransition = false,
19
+ backgroundColorTransition = false,
20
+ boxShadowTransition = false,
21
+ }: Context) {
22
+ return transition(
23
+ [
24
+ colorTransition ? 'color' : null,
25
+ backgroundColorTransition ? 'background-color' : null,
26
+ boxShadowTransition ? 'box-shadow' : null,
27
+ ].filter(isPresent)
28
+ )
29
+ }
30
+
31
+ return createInternal({ toCSS })
32
+ }